package com.selangshiwo ;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSONObject;

public class Main {

	//private final static HttpClient client = new HttpClient();
	private final static HttpClient client = new DefaultHttpClient();

	//dW5kZWZpbmVk = undefined
	static String SSOVERSION = "ssologin.js(v1.3.14)";
	static String SETUP_1 = "http://login.sina.com.cn/sso/prelogin.php?entry=sso&callback=sinaSSOController.preloginCallBack&su=dW5kZWZpbmVk&client="+SSOVERSION ;
	static String SETUP_2 = "http://login.sina.com.cn/sso/login.php?client=" + SSOVERSION;
	static String SETUP_3 = "http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack";
	static String SETUP_4 = "http://weibo.com";
	//static String SETUP_3 = "http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&retcode=101&reason=%B5%C7%C2%BC%C3%FB%BB%F2%C3%DC%C2%EB%B4%ED%CE%F3";
	static HttpResponse response = null ;
	static void loginByWc(String uName , String uPwd) throws Exception{

		HttpClientParams.setCookiePolicy(client.getParams(), CookiePolicy.BROWSER_COMPATIBILITY );
		Map<String , ?> json = null ;
		String sevTime = new Date().getTime() + "";
		String strCookie = "";
		String nonce = "";
		String pcid = "";
		//处理用户名
		uName = uName.replace("@", "%40") ;
		
		log("*******************初始化登陆请求,获取nonce,serverTime等信息******************");
		SETUP_1 = SETUP_1 + "&_="+ new Date().getTime();
		log("GET请求至 : " + SETUP_1 );
		String str_body = get(SETUP_1);	//分析结果,取出nonce,pcid,servertime
		
		log("" + str_body);
		
		str_body = regex(str_body , "\\((.*?)\\)");					//取出必要参数
		
		log("解析返回结果,开始分析..[" + str_body + "]");
		json = string2map(str_body);
		if((Integer)json.get("retcode") != 0){					
			log("获取once失败," + json.toString());
			throw new Exception("获取once失败");
		}else{
			sevTime = ((Integer)json.get("servertime")).toString();
			log("获取servertime---["+sevTime+"]");
			nonce = (String)json.get("nonce");
			log("获取nonce---["+nonce+"]");
			pcid = (String)json.get("pcid");
			log("获取pcid---["+pcid+"]");
			//pcid貌似没用
		}
		//-- setup 1 finished
		//页面中使用 this.hex_sha1
		log("加密密码["+uPwd+"]--------------------");
		uPwd = hex_sha1(hex_sha1(hex_sha1(uPwd)) + sevTime + nonce);	//sha1 password
		log("密码加密返回 -[" + uPwd + "]");

		// 登录表单的信息
		List<NameValuePair> qparams = new ArrayList<NameValuePair>();
		qparams.add(new BasicNameValuePair("encoding", "UTF-8"));
		qparams.add(new BasicNameValuePair("entry", "weibo"));
		qparams.add(new BasicNameValuePair("from", ""));
		qparams.add(new BasicNameValuePair("gateway", "1"));
		qparams.add(new BasicNameValuePair("pwencode", "wsse"));
		qparams.add(new BasicNameValuePair("returntype", "META"));
		qparams.add(new BasicNameValuePair("savestate", "7"));
		qparams.add(new BasicNameValuePair("useticket", "1"));
		qparams.add(new BasicNameValuePair("ssosimplelogin", "1"));
		qparams.add(new BasicNameValuePair("service", "miniblog"));
		qparams.add(new BasicNameValuePair("vsnf", "1"));
		qparams.add(new BasicNameValuePair(
				"url",
		"http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack"));
		qparams.add(new BasicNameValuePair("returntype", "META"));
		qparams.add(new BasicNameValuePair("nonce" , nonce));
		qparams.add(new BasicNameValuePair("prelt" , "1768"));
		qparams.add(new BasicNameValuePair("servertime" , sevTime));
		qparams.add(new BasicNameValuePair("pcid" , pcid));

		uName = base42Encode(uName.getBytes());
		qparams.add(new BasicNameValuePair("su", uName));
		qparams.add(new BasicNameValuePair("sp", uPwd));
		UrlEncodedFormEntity params = new UrlEncodedFormEntity(qparams, "UTF-8");
		
		log("******************登陆统一认证服务器验证************************");
		log("POST->["+SETUP_2+"]");
		log("参数：" + params);
		String str_setup2 = post(SETUP_2 , params);
		//log(str_setup2);
		//Cookie[] cookies = null ;
		log("-------------------请求成功,读取本地Cookie-----------------------");
		List<Cookie> cookies = ((DefaultHttpClient)client).getCookieStore().getCookies();
		for(int i = 0 , len = cookies.size() ; i < len ; i++){
			Cookie cookie = cookies.get(i);
			strCookie += "&" + cookie.getName() + "=" + cookie.getValue();
			log(cookie.getName() + " : " + cookie.getValue());
		}
		//---跳转认证,并获取cookie
		//提取cookie
		//自己找正则提取
		String key1 = "sinaSSOController.setCrossDomainUrlList";
		String key2 = ");}";
		String strResult = str_setup2.substring(str_setup2.indexOf(key1) + key1.length() + 1 , str_setup2.length());	//第一次截取
		log("-------获取远程SSO登记地址：" + strResult);
		strResult = strResult.substring(0 , strResult.indexOf(");"));
		json = (Map<String, ?>) JSONObject.parse(strResult) ;
		List<String> urls = (List)json.get("arrURL");
		//分别请求,好像没啥用,抓包的时候发现请求了,顺带一起请求了。
		for(int len = urls.size() -1 ; len >= 0 ; len --){
			//get
			String url = urls.get(len) ;
			url += "&action=login";
			url += "&callback=sinaSSOController.doCrossDomainCallBack";
			url += "&client=" + SSOVERSION;
			url += "&scriptId=ssoscript" + len;
			log("-----进行远程SSO登记..");
			//log("GET->[" + url + "]");
			//log("RESULT->" + get(url));
		}

		//取weibo跳转url
		key1 = "location.replace(";
		key2 = ");}";
		String strWeiboUrl = str_setup2.substring(str_setup2.indexOf(key1) + key1.length() + 1 , str_setup2.length());	//第一次截取
		strWeiboUrl = strWeiboUrl.substring(0 , strWeiboUrl.indexOf(");") - 1 );
		//strCookie
		log("----FINAL,获取sina Weibo SSO登陆URL->[" + strWeiboUrl + "]");
		String strWeiboLoginInfo = get(strWeiboUrl);

		json = (Map<String , ?>)JSONObject.parse(regex(strWeiboLoginInfo,"\\((.*?)\\)"));
		//log(get("http://weibo.com"));
		log("Weibo Login Result -> [" + json.toString() + "]");
		
		log("*********************转向至Weibo.com完成最后登陆*****************");
		log("-------------------设置userdomain信息---------------");
		String weiboUrl = SETUP_4  + (String)((Map)json.get("userinfo")).get("userdomain");
		log("GET->[" + weiboUrl + "]");
		//因为返回了一个跳转指令
		//weiboUrl = "http://www.qq.com";
		HttpGet get = new HttpGet(weiboUrl);
		response = client.execute(get);
		get.abort(); 
		
		log("*******************所有登陆完成*******************");
		//------打印页面
		//log(dump(response.getEntity()));
		//无法取到头信息中Location,此字段为真实跳转地址,不多做判断,属于缺陷
		//response.getHeaders("Location");
//		Header[] headers = response.getAllHeaders();
//		for(int len = headers.length - 1 ; len >= 0 ; len --){
//			log(headers[len].getName() + " : " + headers[len].getValue());
//		}
//		log(headers.length);
	}
	
	/**
	 * 打印页面
	 * 
	 * @param entity
	 * @throws IOException
	 */
	private static String dump(HttpEntity entity) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(
				entity.getContent(), "utf8"));

		String line = null ;
		while((line = br.readLine()) != null){
			System.out.println(line);
		}
		
		entity.consumeContent() ;
		return "";
	}
	/*
	 * 	临时方式
	 *
	 */
	/**
	 * base64
	 *		openJDK中无此包
	 */
	static String base42Encode(byte[] bstr){
		return new sun.misc.BASE64Encoder().encode(bstr);
	}

	static byte[] base64Decode(String str){
		byte[] out = null ;
		try{
			out = new sun.misc.BASE64Decoder().decodeBuffer(str);
		}catch(Exception e){
			e.printStackTrace();
		}

		return out ;
	}

	static void log(Object text){
		System.out.println(text);
	}

	static String entity2str(HttpEntity entity) throws ParseException, IOException{
		return EntityUtils.toString(entity) ;
	}

	static Map<String , ? > string2map(String str){
		return (Map<String, ?>) JSONObject.parse(str) ;
	}

	static String regex(String text , String regex){		
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(text);
		String out = "";
		if(matcher.find())
			out = matcher.group(1);
		return out ;
	}

	static String get(String url) throws ClientProtocolException, IOException{
		HttpGet httpGet = new HttpGet(url);	//加时间戳
		response = client.execute(httpGet);
		Header[] header = response.getAllHeaders();
		for(int h = header.length - 1; h >= 0 ; h --){
			log(header[h].getName() + " : " + header[h].getValue());
		}
		httpGet.abort() ;
		return entity2str(response.getEntity());
	}

	static String post(String url , UrlEncodedFormEntity params) throws ClientProtocolException, IOException{
		HttpPost httpPost = new HttpPost(url);
		httpPost.setHeader("User-Agent",
		"Mozilla/5.0 (X11; Linux i686; rv:5.0) Gecko/20100101 Firefox/5.0");
		httpPost.setHeader("Referer", "http://weibo.com/");
		httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
		httpPost.setEntity(params);
		response = client.execute(httpPost);
		httpPost.abort();
		return entity2str(response.getEntity());
	}

	static String hex_sha1(String in) throws NoSuchAlgorithmException{
		String out = "";
		String encType = "SHA";
		MessageDigest md = MessageDigest.getInstance(encType);
		md.update(in.getBytes());
		out = byte2hex(md.digest());
		return out ;
	}

	static String byte2hex(byte[] in){
		String out = "";
		String tmp = null ;
		for (int i=0 , len = in.length ;i < len ; i++) {
			tmp=(Integer.toHexString(in[i] & 0xFF));
			if (tmp.length()==1) {
				out+="0";
			}
			out+=tmp;
		}
		return out;
	}

	public static void main(String[] args) throws Exception {
		//login("617254428@qq.com", "880621");
		//String result = get("http://t.sina.com.cn/pub/tags");
		//System.out.println(result);
		//105661419@qq.com  123456789
		loginByWc("617254428@qq.com","880621");
		
		//95740132e93d97e33e7950f394bc19ecd87a28a0	sha1(sha1(sha1(pwd)) + sevTime + once)
		//1338348669
		//BH2DC8
		//wsse
		//2420
	}

}